package com.cq;

import java.net.InetAddress;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Random;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

/**
 * 工具类
 * 
 */
public class UtilDate {

	private static String ip_str = "";
	
	/** 年月日时分秒(无下划线) yyyyMMddHHmmss */
	public static final String dtLong = "yyyyMMddHHmmss";

	/** 完整时间 yyyy-MM-dd HH:mm:ss */
	public static final String simple = "yyyy-MM-dd HH:mm:ss";

	/** 年月日(无下划线) yyyyMMdd */
	public static final String dtShort = "yyyyMMdd";

	/** 年月日(有下划线) yyyy-MM-dd */
	public static final String dtmedium = "yyyy-MM-dd";
	
	/** 年月日(有斜线) yyyy/MM/dd */
	public static final String dtmediumNew = "yyyy/MM/dd";

	private static final Logger logger = Logger.getLogger(UtilDate.class);

	/**
	 * 返回系统当前时间(精确到毫秒),作为一个唯一的时间编号
	 * 
	 * @return 以yyyyMMddHHmmss为格式的当前系统时间
	 */
	public static String getTimeNum() {
		Date date = new Date();
		DateFormat df = new SimpleDateFormat(dtLong);
		return df.format(date);
	}

	/**
	 * 返回时间(精确到毫秒),作为一个唯一的时间编号
	 * 
	 * @return 以yyyyMMddHHmmss为格式的当前系统时间
	 */
	public static String getTimeNumByDate(Date date) {
		DateFormat df = new SimpleDateFormat(dtLong);
		return df.format(date);
	}

	/**
	 * 获取系统当前日期(精确到毫秒)，格式：yyyy-MM-dd HH:mm:ss
	 * 
	 * @return
	 */
	public static String getDateFormatter() {
		Date date = new Date();
		DateFormat df = new SimpleDateFormat(simple);
		return df.format(date);
	}

	/**
	 * 获取日期(精确到毫秒)，格式：yyyy-MM-dd HH:mm:ss
	 * 
	 * @return
	 */
	public static String getDateFormatter(Date date) {
		DateFormat df = new SimpleDateFormat(simple);
		return df.format(date);
	}

	/**
	 * 获取日期 格式yyyy-mm-dd
	 * 
	 * @param date
	 * @return
	 */
	public static String getDateFormatterMedium(Date date) {
		DateFormat df = new SimpleDateFormat(dtmedium);
		return df.format(date);
	}

	/**
	 * 获取系统当期年月日(精确到天)，格式：yyyyMMdd
	 * 
	 * @return
	 */
	public static String getDateStr(Date date) {
		DateFormat df = new SimpleDateFormat(dtShort);
		return df.format(date);
	}

	/**
	 * 通过字符串获取 时间 格式 为"yyyy-MM-dd HH:mm:ss"
	 * 
	 * @param dateStr
	 * @return
	 */
	public static Date getDateFromStr(String dateStr) {
		SimpleDateFormat sdf = new SimpleDateFormat(simple);
		Date resultDate = null;
		try {
			resultDate = sdf.parse(dateStr);
		} catch (ParseException e) {
			logger.error("dateStr = " + dateStr + " can't change to Date!");
			logger.error(e.getMessage());
			resultDate = new Date();
		}
		return resultDate;
	}

	/**
	 * 通过字符串获取 时间 格式 为"yyyyMMdd"
	 * 
	 * @param dateStr
	 * @return
	 */
	public static Date getDateFromBaseStr(String dateStr) {
		SimpleDateFormat sdf = new SimpleDateFormat(dtShort);
		Date resultDate = null;
		try {
			resultDate = sdf.parse(dateStr);
		} catch (ParseException e) {
			logger.error("dateStr = " + dateStr + " can't change to Date!");
			logger.error(e.getMessage());
			resultDate = new Date();
		}
		return resultDate;
	}

	/**
	 * 通过字符串获取时间 格式 yyyy-MM-dd
	 * 
	 * @param dateStr
	 * @return
	 */
	public static Date getDateFromMediumStr(String dateStr) {
		SimpleDateFormat sdf = new SimpleDateFormat(dtmedium);
		Date resultDate = null;
		try {
			resultDate = sdf.parse(dateStr);
		} catch (ParseException e) {
			logger.error("dateStr = " + dateStr + " can't change to Date!");
			logger.error(e.getMessage());
			resultDate = new Date();
		}
		return resultDate;
	}
	
	
	/**
	 * 通过字符串获取时间 格式 yyyy/MM/dd
	 * 
	 * @param dateStr
	 * @return
	 */
	public static Date getDateFromMediumNewStr(String dateStr) {
		SimpleDateFormat sdf = new SimpleDateFormat(dtmediumNew);
		Date resultDate = null;
		try {
			resultDate = sdf.parse(dateStr);
		} catch (ParseException e) {
			logger.error("dateStr = " + dateStr + " can't change to Date!");
			logger.error(e.getMessage());
			resultDate = new Date();
		}
		return resultDate;
	}

	/**
	 * 通过字符串获取 时间 格式 为"yyyy-MM-dd HH:mm:ss"
	 * 
	 * @param dateStr
	 * @return
	 */
	public static Date getDate() {
		return new Date();
	}

	/**
	 * 将一个"yyyyMMddHHmm"字符串转成日期格式
	 */
	public static Date getDateByString(String str) {
		Date time = null;
		try {
			SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmm");
			time = sf.parse(str);
		} catch (Exception e) {
			logger.error(e.getMessage());
			return null;
		}
		return time;
	}

	/**
	 * 将一个"yyyyMMddHHmm"字符串转成日期格式
	 */
	public static Date getDateByString(String str, String formate) {
		Date time = null;
		try {
			SimpleDateFormat sf = new SimpleDateFormat(formate);
			time = sf.parse(str);
		} catch (Exception e) {
			logger.error(e.getMessage());
			return null;
		}
		return time;
	}

	/**
	 * 产生随机的三位数
	 * 
	 * @return
	 */
	public static String getThree() {
		Random rad = new Random();
		return rad.nextInt(1000) + "";
	}

	/**
	 * 返回系统当前时间之后的时间单位是分钟(精确到毫秒),作为一个唯一的时间编号
	 * 
	 * @param item_minute
	 * @return
	 */
	public static String getTimeNumByMinute(int item_minute) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MINUTE, item_minute);
		DateFormat df = new SimpleDateFormat(dtLong);
		return df.format(calendar.getTime());
	}

	/**
	 * 返回系统当前时间之前的时间单位是天
	 * 
	 * @param day
	 *            几天前
	 * @return 返回时间格式为yyyy-MM-dd
	 */
	public static String getTimeNumBeforeByDay(int day) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - day);
		DateFormat df = new SimpleDateFormat(dtmedium);
		return df.format(calendar.getTime());
	}

	/**
	 * 返回系统当前时间之后的时间单位是天
	 * 
	 * @param day
	 *            几天后
	 * @return 返回时间格式为yyyy-MM-dd
	 */
	public static String getTimeNumAfterByDay(int day) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + day);
		DateFormat df = new SimpleDateFormat(dtmedium);
		return df.format(calendar.getTime());
	}
	
	
	/**
	 * 天数比较
	 * 
	 * @param fDate开始天数
	 * @param oDate结束天数
	 * @return
	 */
	public static int daysOfTwo(Date f_date, Date o_date) {

		Calendar aCalendar = Calendar.getInstance();

		aCalendar.setTime(f_date);
		
		//获取开始年份
		int f_year = aCalendar.get(Calendar.YEAR);

		//当年的多少天
		int day1 = aCalendar.get(Calendar.DAY_OF_YEAR);

		aCalendar.setTime(o_date);

		//获取结束年份		
		int o_year = aCalendar.get(Calendar.YEAR);
		int day2 = aCalendar.get(Calendar.DAY_OF_YEAR);
		
		if(f_year < o_year){
			for(int i = 0;i <(o_year-f_year);i++ ){
				Calendar cal = Calendar.getInstance();
				cal.set(Calendar.YEAR, f_year+i);
				cal.getActualMaximum(Calendar.DAY_OF_YEAR);
				day2 += cal.getActualMaximum(Calendar.DAY_OF_YEAR);
			}		
		}else if(f_year > o_year){
			for(int i = 0;i <(f_year-o_year);i++ ){
				Calendar cal = Calendar.getInstance();
				cal.set(Calendar.YEAR, o_year+i);
				cal.getActualMaximum(Calendar.DAY_OF_YEAR);
				day1 += cal.getActualMaximum(Calendar.DAY_OF_YEAR);
			}
		}

		return day2 - day1;

	}
	
	/**
     * 获取当月最后1天
     */
	public static Date getLastDayByMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
		return cal.getTime();
	}
	
	/** 
     * 获取当年的第一天 
     * @param year 
     * @return 
     */  
    public static Date getCurrYearFirst(){  
        Calendar currCal=Calendar.getInstance();    
        int currentYear = currCal.get(Calendar.YEAR);  
        return getYearFirst(currentYear);  
    }  
      
    /** 
     * 获取当年的最后一天 
     * @param year 
     * @return 
     */  
    public static Date getCurrYearLast(){  
        Calendar currCal=Calendar.getInstance();    
        int currentYear = currCal.get(Calendar.YEAR);  
        return getYearLast(currentYear);  
    }
    
    /** 
     * 获取某年第一天日期 
     * @param year 年份 
     * @return Date 
     */  
    public static Date getYearFirst(int year){  
        Calendar calendar = Calendar.getInstance();  
        calendar.clear();  
        calendar.set(Calendar.YEAR, year);  
        Date currYearFirst = calendar.getTime();  
        return currYearFirst;  
    }  
      
    /** 
     * 获取某年最后一天日期 
     * @param year 年份 
     * @return Date 
     */  
    public static Date getYearLast(int year){  
        Calendar calendar = Calendar.getInstance();  
        calendar.clear();  
        calendar.set(Calendar.YEAR, year);  
        calendar.roll(Calendar.DAY_OF_YEAR, -1);  
        Date currYearLast = calendar.getTime();  
          
        return currYearLast;  
    } 
	
	/**
	 * 获取大于或者小于指定日期的日期
	 * @param date 指定日期
	 * @param day 1表示明天|-1表示昨天
	 * @return
	 */
	public static Date getBeforeMonth(Date date, int month) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, month);
		return cal.getTime();
	}
	
	/**
     * 通过毫秒值，手动计算日期间的相关的值
     *
     * 跨年不会出现问题
     * 使用此种方法的话需要注意
     * 如果时间为：2016-03-18 11:59:59 和 2016-03-19 00:00:01的话差值为 0
     *
     * @throws ParseException
     */
    public static int daysOfTwo2(Date f_date, Date o_date){
    	int days= (int) ((o_date.getTime()-f_date.getTime())/(1000*3600*24));
		return days;
    }

	/**
	 * 获取翻单货期时间(默认大于当前21天)
	 * 
	 * @param now
	 *            当前时间
	 * @param day
	 *            期限天数
	 * @return 货期时间(yyyy-MM-dd HH:mm:ss )
	 */
	public static Date getTurnDate(Date now, int day) {
		Date date = null;// 当前日期
		SimpleDateFormat sdf = new SimpleDateFormat(UtilDate.simple);// 格式化对象
		Calendar calendar = Calendar.getInstance();// 日历对象
		calendar.setTime(now);// 设置当前日期
		calendar.add(Calendar.DAY_OF_YEAR, day);
		try {
			date = sdf.parse(sdf.format(calendar.getTime()));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * 校验:是否为正确的日期格式
	 * 
	 * @param time
	 * @param format
	 * @return
	 */
	public static boolean isValidDate(String time, String format) {
		try {
			// 指定日期格式为四位年/两位月份/两位日期，注意yyyy-MM-dd其中MM为大写
			SimpleDateFormat dateFormat = new SimpleDateFormat(format);
			// 设置lenient为false.
			// 否则SimpleDateFormat会比较宽松地验证日期，比如2004/02/29会被接受，并转换成2004/03/01
			dateFormat.setLenient(false);
			dateFormat.parse(time);
			return true;
		} catch (Exception e) {
			// 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
			return false;
		}
	}

	/**
	 * 解析String成Date
	 * 
	 * @param time
	 * @param format
	 * @return
	 */
	public static Date parseDateStr(String time, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		Date result = null;
		try {
			result = sdf.parse(time);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return result;
	}

	/**
	 * 将时间转换成指定格式的字符日期
	 * @param date
	 * @param formate
	 * @return
	 */
	public static String getStrDateByFormate(Date date, String formate) {
		SimpleDateFormat sdf = new SimpleDateFormat(formate);
		return sdf.format(date);
	}
	
	public static void main(String[] args) {
		String temp = "1994-01-13";
		String temp2 = "1994-01-13 12:12:12";
		System.out.println(getDateFromMediumStr(temp));
		System.out.println(getDateFromMediumStr(temp2));
	}
	
	/**
	 * 获取本机IP
	 * 
	 * @return
	 */
	public static String getLocalhostIp() {
		if (StringUtils.isBlank(ip_str)) {
			try {
				InetAddress addr = InetAddress.getLocalHost();
				ip_str = addr.getHostAddress();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return ip_str;
	}
	
	/**
	 * 获取指定日期的后i天
	 * 
	 * @return
	 */
	public static Date getRightDate(String str,int i){
		Date date = getDateFromMediumStr(str);
		 Calendar calendar = new GregorianCalendar(); 
	     calendar.setTime(date); 
	     calendar.add(Calendar.DATE,i);//把日期往后增加一天.整数往后推,负数往前移动 
	     date=calendar.getTime();  
	     return date;
	}
}
